{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Terra's Orbit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<i>© Von P. Walden, Washington State University</i>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook describes how to use the PyEphem module to calculate ephemeris data for NASA Terra's satellite.  It relies on up-to-date orbital \"two-line element\" (TLE) data from NORAD; http://celestrak.com/NORAD/elements/science.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Populating the interactive namespace from numpy and matplotlib\n"
     ]
    }
   ],
   "source": [
    "%pylab inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "ename": "ModuleNotFoundError",
     "evalue": "No module named 'ephem'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-2-99cf1a717562>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mephem\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0murllib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrequest\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0murlopen\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;31m# Obtain the most recent orbital \"elements\" data from NORAD auto-magically!\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0mTLEs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0murlopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'http://celestrak.com/NORAD/elements/science.txt'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreadlines\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'ephem'"
     ]
    }
   ],
   "source": [
    "import ephem\n",
    "from urllib.request import urlopen\n",
    "\n",
    "# Obtain the most recent orbital \"elements\" data from NORAD auto-magically!\n",
    "TLEs = urlopen('http://celestrak.com/NORAD/elements/science.txt').readlines()\n",
    "for i,TLE in enumerate(TLEs):\n",
    "    if TLE.decode('utf-8').count('TERRA'):\n",
    "        l1 = TLEs[i].strip().decode('utf-8')\n",
    "        l2 = TLEs[i+1].strip().decode('utf-8')\n",
    "        l3 = TLEs[i+2].strip().decode('utf-8')\n",
    "terra = ephem.readtle(l1,l2,l3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "TLEs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The TLE data format is explained here: https://en.wikipedia.org/wiki/Two-line_element_set"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "b'TERRA                   \\r\\n',\n",
    " b'1 25994U 99068A   19233.87854381 -.00000044  00000-0  22564-6 0  9997\\r\\n',\n",
    " b'2 25994  98.2014 307.4535 0001211 111.3085 248.8225 14.57116811 46541\\r\\n',\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "from datetime import datetime, timedelta\n",
    "\n",
    "# Create datetimes for the next three days.\n",
    "numberOfDays = 1\n",
    "now = datetime.date(datetime.now())\n",
    "midnight = datetime(now.year, now.month, now.day, 0, 0)\n",
    "dt  = [midnight + timedelta(minutes=x) for x in range(0, numberOfDays*24*60, 1)]\n",
    "\n",
    "# Compute ground track locations at each datetime\n",
    "sublon, sublat = np.array([]), np.array([])\n",
    "for date in dt:\n",
    "    terra.compute(date)\n",
    "    sublon = append(sublon, np.rad2deg(terra.sublong)+180.)\n",
    "    sublat = append(sublat, np.rad2deg(terra.sublat))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "plt.figure(figsize(16,6))\n",
    "ax = plt.subplot(2,1,1)\n",
    "ax.axis([min(dt), max(dt), 0, 360])\n",
    "plot(dt,sublon)\n",
    "ax = plt.subplot(2,1,2)\n",
    "ax.axis([min(dt), max(dt), -90, 90])\n",
    "plot(dt,sublat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Current location of satellite.\n",
    "terra.compute(datetime.now())\n",
    "x, y  = (sublon, sublat)\n",
    "x2,y2 = (np.rad2deg(terra.sublong)+180.,np.rad2deg(terra.sublat))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import cartopy.crs as ccrs\n",
    "\n",
    "fig = plt.figure(figsize=(16, 12))\n",
    "ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree(central_longitude=180))\n",
    "\n",
    "ax.set_title('Recent Tracks and Current Position of Terra Satellite')\n",
    "ax.stock_img()\n",
    "ax.plot(x, y,'k.', markersize=3, transform=ccrs.PlateCarree())\n",
    "ax.plot(x2, y2,'y*', markersize=20, transform=ccrs.PlateCarree())\n",
    "plt.show()\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  },
  "widgets": {
   "state": {},
   "version": "1.1.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
